<?php
/**
 * Zend_Auth
 */
require_once 'Zend/Auth.php';
class MAIN_Auth
{
    /**
     * Singleton instance
     *
     * @var package_name
     */
    protected static $_instance = null;

    /**
     * Persistent storage handler
     *
     * @var Zend_Auth_Storage_Interface
     */
    protected $_storage = null;

    protected $_storageName;

    protected static $_authAdapter = null;

    protected $_adapter;

    protected $_adapterType;

    protected $_identity;

    protected $_credential;

    protected $_options = array(
        'db'=>array(
            'adapter'                => null,
            'tableName'              => null,
            'identityColumn'         => null,
            'credentialColumn'       => null,
            'credentialTreatment'    => null
        ),
        'http'=>array(
            'accept_schemes'         => 'basic',               //'basic'|'digest'|'basic digest'
            'realm'                  => 'HTTP Authentication', //<string>
            'digest_domains'         => '',                    //<string> Space-delimited list of URIs
            'nonce_timeout'          => 60,                    //<int>
            'use_opaque'             => false,                 // <bool> Whether to send the opaque value in the header
            'alogrithm'              =>  array('MD5'),         // <string> See $_supportedAlgos. Default: MD5
            'proxy_auth'             => false                  //<bool> Whether to do authentication as a Proxy
        ),
        'ldap'=>array(
            'host'                   => null,
            'port'                   => null,
            'useSsl'                 => null,
            'username'               => null,
            'password'               => null,
            'bindRequiresDn'         => null,
            'baseDn'                 => null,
            'accountCanonicalForm'   => null,
            'accountDomainName'      => null,
            'accountDomainNameShort' => null,
            'accountFilterFormat'    => null
        ),
        'openid' => array(
            'id' => null,
            'storage' => null,
            'returnTo' => null,
            'root' => null,
            'extensions' => null,
            'response' => null
        )
    );

    //protected $_options = array('');

    /**
     * Singleton pattern implementation makes "new" unavailable
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * Returns an instance of package_name
     *
     * Singleton pattern implementation
     *
     * @return package_name Provides a fluent interface
     */
    public static function getInstance()
    {
        if (null === self::$_instance) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    public function setIdentity($identity){ $this->_identity = $identity; }

    public function setCredential($credential){ $this->_credential = $credential; }

    public function setAdapterType($type) {
        $this->_adapterType = $type;
    }

    public function setAuthAdapter($adapterType=null, $options) {
        if(null != $adapterType) {
            $this->setAdapterType($adapterType);
        }
/*
        if(isset($options['username'])) {
            $this->setStorageName($options['username']);
        }
*/
        switch (strtolower($this->_adapterType)) {
        	case 'db':
                 self::$_authAdapter=$this->_setDbAdapter($options);
        		break;
            case 'ldap':
                self::$_authAdapter=$this->_setLdapAdapter($options);
                break;
            case 'openid':
                self::$_authAdapter=$this->_setOpenIdAdapter($options);
                break;

        	default:
        		break;
        }
    }

    public function setStorageName($name) {
        $this->_storageName = $name;
    }

    private function _setDbAdapter($options) {
        // setup Zend_Auth adapter for a database table;
        if(!class_exists('Zend_Auth_Adapter_DbTable'))
            Zend_Loader :: loadClass('Zend_Auth_Adapter_DbTable');

        $opts = $this->setAdapterOptions($options);

        if($opts['adapter'] instanceof Zend_Db) {
            return new Zend_Auth_Adapter_DbTable(
                $opts['adapter'],
                $opts['tableName'],
                $opts['identityColumn'],
                $opts['credentialColumn'],
                $opts['credentialTreatment']
            );
        } else if(Zend_Registry::isRegistered('db')) {
            return new Zend_Auth_Adapter_DbTable(Zend_Registry :: get('db'),
                $opts['tableName'],
                $opts['identityColumn'],
                $opts['credentialColumn'],
                $opts['credentialTreatment']
            );
        } else {
            return null;
        }
    }

    private function _setLdapAdapter($options) {
        if(!class_exists('Zend_Auth_Adapter_Ldap'))
            Zend_Loader :: loadClass('Zend_Auth_Adapter_Ldap');
        //$opts = $this->setAdapterOptions($options);
        return new Zend_Auth_Adapter_Ldap($options, $this->_identity,$this->_credential);
    }

    private function _setOpenIdAdapter($options) {
        if(!class_exists('Zend_Auth_Adapter_OpenId'))
            Zend_Loader :: loadClass('Zend_Auth_Adapter_OpenId');
        (object)$opt = $this->setAdapterOptions($options);
        return new Zend_Auth_Adapter_OpenId($opt->id, $opt->storage,$opt->returnTo,$opt->root,$opt->extensions,$opt->response);
    }

    public function setAdapterOptions($options) {
        if(array_key_exists($this->_adapterType,$this->_options)) {
            foreach($options as $key=>$value){
                if(array_key_exists($key,$this->_options[$this->_adapterType]) && isset($value)){
                    $this->_options[$this->_adapterType][$key]=$value;
                }
            }
        }
        return $this->_options[$this->_adapterType];
    }

    public function getAdapterOptions($adapter_key=null){
        if(array_key_exists($adapter_key,$this->_options)) {
            return $this->_options[$adapter_key];
        } else {
            return $this->_options;
        }
    }

    public function getStorage()
    {
        if (null === $this->_storage) {
            /**
             * @see Zend_Auth_Storage_Session
             */
            require_once 'Zend/Auth/Storage/Session.php';
            $this->setStorage(new Zend_Auth_Storage_Session());
        }
        return $this->_storage;
    }

    /**
     * Sets the persistent storage handler
     *
     * @param  Zend_Auth_Storage_Interface $storage
     * @return Zend_Auth_Storage_Interface Provides a fluent interface
     */
    public function setStorage(Zend_Auth_Storage_Interface $storage)
    {
        $this->_storage = $storage;
        return $this;
    }
	public function getAuthSearch(){
		$resource = $this->getAuthAdapter()->getLdap()->getResource();
		$test = ldap_connect("172.19.0.245");
		$_option = $this->getAuthAdapter()->getLdap()->getOptions();
		//_print($_option[baseDn]);
		//_print($test);
		//_print($_option[baseDn]);
		//echo "(UID=".$this->_identity.")";

		$result = ldap_search($test, $_option[baseDn], "(uid=".$this->_identity.")");
    	$entries = ldap_get_entries($test, $result);
//		echo "User count: " . $entries["count"] . "<br /><br /><b>Users:</b><br />";
//	    for ($i=0; $i < $entries["count"]; $i++) {
//	        foreach($entries[$i] as $field=>$data){
//	        	if(is_numeric($field)) continue;
//	        	$rows[$field]=$data[0];
//	        }
//	    }
//	    die();
	    return $entries["count"];
	}
    public function getAuthAdapter() {
        if(null === self::$_authAdapter) {
            // setup Zend_Auth adapter for a database table;
            if(!class_exists('Zend_Auth_Adapter_DbTable'))
                Zend_Loader :: loadClass('Zend_Auth_Adapter_DbTable');

            if(Zend_Registry::isRegistered('db')) {
                $dbAdapter   = Zend_Registry :: get('db');
                self::$_authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
            }
        }
        return self::$_authAdapter;
    }

    public function authenticate()
    {
        $adapter = $this->getAuthAdapter();
        $result = $adapter->authenticate();

        if ($result->isValid()) {
            $this->getStorage()->write($result->getIdentity());
        }

        return $result;
    }

    /**
     * Returns true if and only if an identity is available from storage
     *
     * @return boolean
     */
    public function hasIdentity()
    {
        return !$this->getStorage()->isEmpty();
    }

    /**
     * Returns the identity from storage or null if no identity is available
     *
     * @return mixed|null
     */

    public function getIdentity()
    {
        $storage = $this->getStorage();

        if ($storage->isEmpty()) {
            return null;
        }

        return $storage->read();
    }

    /**
     * Clears the identity from persistent storage
     *
     * @return void
     */
    public function clearIdentity()
    {
        $this->getStorage()->clear();
    }
}
